# vim: fileencoding=utf-8
#!-*- coding:utf-8 -*-
#日本語
import cgi
import re
import logging
from django.utils import simplejson
import os
import wsgiref.handlers
import datetime
from google.appengine.api import users
from google.appengine.ext import db,webapp
from google.appengine.ext.webapp import template
from google.appengine.api import memcache
from common import Category,DayReserve,Spending,Daymemo
import common
import string
import csv
from StringIO import StringIO

class CategoryList(webapp.RequestHandler):
  def get(self):
    path = os.path.join(os.path.dirname(__file__), 'category.html')
    self.response.out.write(template.render(path, {}))

class AddCategory(webapp.RequestHandler):
  def post(self):
    name = self.request.get("name")
    user = users.get_current_user()
    position = Category.all().filter('user',user).count()
    category = Category(name=name,user=user,position=position)
    category.put()
class MainPage(webapp.RequestHandler):
  def get(self):
    path = os.path.join(os.path.dirname(__file__), 'index.html')
    self.response.out.write(template.render(path, {}))

  def post(self):
    user = users.get_current_user()
    common.add_account(self,user) 
    self.redirect("/")

class GetMemoListData(webapp.RequestHandler):
  def get(self):
    user = users.get_current_user()
    from_year= int(self.request.get("from_year"))
    from_month= int(self.request.get("from_month"))
    from_day = int(self.request.get("from_day"))
    from_date = datetime.datetime(from_year,from_month,from_day)

    to_year= int(self.request.get("to_year"))
    to_month= int(self.request.get("to_month"))
    to_day = int(self.request.get("to_day"))
    to_date = datetime.datetime(to_year,to_month,to_day)

    datas = Daymemo.all().filter('user',user).filter('date >=',from_date).filter('date <=',to_date).order('date')
    dataarr = []
    for data in datas:
      dataarr.append({
                      'year':data.date.year,
                      'month':data.date.month,
                      'date':data.date.day,
                      'memo':data.memo,
                      })
    self.response.headers['Content-Type'] = 'application/json'
    self.response.out.write(simplejson.dumps(dataarr))
class GetMemoData(webapp.RequestHandler):
  def get(self):
    user = users.get_current_user()
    year= int(self.request.get("account_year"))
    month= int(self.request.get("account_month"))
    day = int(self.request.get("account_day"))
    date = datetime.datetime(year,month,day)
    data = Daymemo.all().filter('user',user).filter('date =',date)
    memo = ""
    if data.count() != 0:
        memo = data[0].memo
    self.response.headers['Content-Type'] = 'application/json'
    self.response.out.write(simplejson.dumps({'memo':memo}))

class SetMemoData(webapp.RequestHandler):
  def post(self):
    user = users.get_current_user()
    year= int(self.request.get("account_year"))
    month= int(self.request.get("account_month"))
    day = int(self.request.get("account_day"))
    date = datetime.datetime(year,month,day)
    data = Daymemo.all().filter('user',user).filter('date =',date)
    memoData = None
    if data.count() == 0:
        memoData  = Daymemo(memo=self.request.get("memo"),user=user,date=date)
    else:
        memoData = data[0]
        memoData.memo = self.request.get("memo")
    memoData.put()
    self.response.headers['Content-Type'] = 'application/json'
    self.response.out.write(simplejson.dumps({'memo':memoData.memo}))

class GetTotalAccountData(webapp.RequestHandler):
  def get(self):
    user = users.get_current_user()
    year= int(self.request.get("account_year"))
    month= int(self.request.get("account_month"))
    accounts = memcache.get(user.nickname()+str(year)+str(month)+"sum")
    if accounts is None:
        common.setUserMonthAccount(user=user,year=year,month=month)
        accounts = memcache.get(user.nickname()+str(year)+str(month)+"sum")
    self.response.out.write(accounts)
class GetCategories(webapp.RequestHandler):
  def get(self):
    user = users.get_current_user()
    datas = Category.all().filter('user',user).order('position')
    categories=[]
    for data in datas:
      key_val = data.key()
      categories.append({'key':str(key_val),'name':data.name})
    self.response.headers['Content-Type'] = 'application/json'
    self.response.out.write(simplejson.dumps(categories))

class GetAccountList(webapp.RequestHandler):
  def get(self):
    user = users.get_current_user()
    from_year= int(self.request.get("from_year"))
    from_month= int(self.request.get("from_month"))
    from_day = int(self.request.get("from_day"))
    from_date = datetime.datetime(from_year,from_month,from_day)

    to_year= int(self.request.get("to_year"))
    to_month= int(self.request.get("to_month"))
    to_day = int(self.request.get("to_day"))
    to_date = datetime.datetime(to_year,to_month,to_day)
    key=self.request.get("category")
    datas=None
    if key:
      datas = Spending.all().filter('user',user).filter('date >=',from_date).filter('date <= ',to_date).filter('category',db.Key(key)).order('date')
    else:
      datas = Spending.all().filter('user',user).filter('date >=',from_date).filter('date <= ',to_date).order('date')
    dataarr = []
    for data in datas:
      dataarr.append({
                      'year':data.date.year,
                      'month':data.date.month,
                      'date':data.date.day,
                      'category':data.category.name,
                      'price':data.price,
                      'content':data.content,
                      'key':str(data.key())
                      })
    self.response.headers['Content-Type'] = 'application/json'
    self.response.out.write(simplejson.dumps(dataarr))

class LineGraphData(webapp.RequestHandler):
  def get(self):
    user = users.get_current_user()
    totalData = {}
    accountData = None
    if(self.request.get("type")=="day"):
      year= int(self.request.get("day_year"))
      month= int(self.request.get("day_month"))
      day = int(self.request.get("day_day"))
      from_day = datetime.datetime(year,month,day) 
      for idx in range(14):
        if idx != 0:
          date =  from_day + datetime.timedelta(idx)
        else:
          date = from_day
        datas = None
        datas = Spending.all().filter('user',user).filter('date =',date)
        dateStr = str(date.month)+"/"+str(date.day)
        totalData[dateStr] = {}
        for data in datas:
          categoryData = totalData[dateStr]
          if data.category.name in categoryData:
            categoryData[data.category.name] += data.price
          else:
            categoryData[data.category.name] = data.price
          totalData[dateStr] = categoryData
    else:
      year= int(self.request.get("month_year"))
      month= int(self.request.get("month_month"))
      for idx in range(13):
        f=common.appendMonth(year,month,idx)
        accounts = memcache.get(user.nickname()+str(f["year"])+str(f["month"])+"sum")
        if accounts is None:
           accountData= common.setUserMonthAccount(user=user,year=f["year"],month=f["month"])
        else:
           accountData = simplejson.loads(accounts)
        totalData[str(f["year"])[2:4] + "/" + str(f["month"])] = accountData
    self.response.headers['Content-Type'] = 'application/json'
    self.response.out.write(simplejson.dumps(totalData))

class ChartGraphData(webapp.RequestHandler):
  def get(self):
    user = users.get_current_user()
    accounts = None
    accountData = None
    totalAccountData = {}
    if(self.request.get("chart")=="year"):
      year= int(self.request.get("cy_year"))
      for i in range(1,13): 
        accounts = memcache.get(user.nickname()+str(year)+str(i)+"sum")
        if accounts is None:
          accountData= common.setUserMonthAccount(user=user,year=year,month=i)
        else:
          accountData = simplejson.loads(accounts)
          for acData in accountData:
            if acData in totalAccountData:
              totalAccountData[acData] += accountData[acData]
            else:
              totalAccountData[acData] = accountData[acData]
    else:
      year= int(self.request.get("cm_year"))
      month= int(self.request.get("cm_month"))
      accounts = memcache.get(user.nickname()+str(year)+str(month)+"sum")
      if accounts is None:
        totalAccountData= common.setUserMonthAccount(user=user,year=year,month=month)
      else:
        totalAccountData = simplejson.loads(accounts)
    self.response.headers['Content-Type'] = 'application/json'
    self.response.out.write(simplejson.dumps(totalAccountData))

class GetAccountData(webapp.RequestHandler):
  def get(self):
    user = users.get_current_user()
    year= int(self.request.get("account_year"))
    month= int(self.request.get("account_month"))
    day = int(self.request.get("account_day"))
    date = datetime.datetime(year,month,day)
    datas = db.GqlQuery("select * FROM Spending"
                                   " where user = :user"
                                   " and date = :date", user=user,date = date)
    dataarr = []
    for data in datas:
      key_val = data.key()
      dataarr.append({'category':data.category.name,
                      'price':data.price,
                      'content':data.content,
                      'key':str(key_val)
                      })
    self.response.headers['Content-Type'] = 'application/json'
    self.response.out.write(simplejson.dumps(dataarr))

class GetReserveList(webapp.RequestHandler):
  def get(self):
    user = users.get_current_user()
    datas = db.GqlQuery("select * FROM DayReserve"
                                   " where user = :user" , user=user)
    dataarr = []
    for data in datas:
      key_val = data.key()
      dataarr.append({'day':data.day,
                      'category':data.category.name,
                      'price':data.price,
                      'content':data.content,
                      'key':str(key_val)
                      })
    self.response.headers['Content-Type'] = 'application/json'
    self.response.out.write(simplejson.dumps(dataarr))

class AddAccount(webapp.RequestHandler):
  def post(self):
    user = users.get_current_user()
    common.add_account(self,user)

class AddDayReserve(webapp.RequestHandler):
  def post(self):
    user = users.get_current_user()
    content = self.request.get("content")
    price = int(self.request.get("price"))
    day = int(self.request.get("day"))
    category = self.request.get("category")
    reserve = DayReserve(user=user,
                      day=day,
                      content=content,
                      price = price)
    reserve.category=db.Key(category)
    reserve.put()

class DeleteAccountData(webapp.RequestHandler):
  def post(self):
    key = self.request.get("key")
    user = users.get_current_user()
    account = db.get(db.Key(key))
    if account.user != user:
      self.response.set_status(403)
      return
    common.setMemCacheData(user,account.category,account.date.year,account.date.month,-1*account.price);
    account.delete()
    self.redirect("/")
class DeleteCategoryData(webapp.RequestHandler):
  def post(self):
    key = self.request.get("key")
    category = db.get(db.Key(key))
    user = users.get_current_user()
    if category.user != user:
      self.response.set_status(403)
      return
    spendings = Spending.all().filter('category',category)
    reserves = DayReserve.all().filter('category',category)

    if spendings.count()==0 and  reserves.count() ==0:
      category.delete()
    else:
      msg=""
      for spend in spendings:
        msg += "account "+ str(spend.date.year) + "/"+ str(spend.date.month)+ "/"+ str(spend.date.day)+" "+spend.content+"\n"
      for reserve in reserves:
        msg += "reserve "+ str(reserve.day) + ":"+ str(reserve.content)+"\n"
      msg="Delete first before remove category!!\n"+msg
      self.response.set_status(403)
      self.response.out.write(msg)

class ListAccount(webapp.RequestHandler):
  def get(self):
    path = os.path.join(os.path.dirname(__file__), 'listaccount.html')
    self.response.out.write(template.render(path, {}))

class ListMemo(webapp.RequestHandler):
  def get(self):
    path = os.path.join(os.path.dirname(__file__), 'listmemo.html')
    self.response.out.write(template.render(path, {}))

class LineGraph(webapp.RequestHandler):
  def get(self):
    path = os.path.join(os.path.dirname(__file__), 'linegraph.html')
    self.response.out.write(template.render(path, {}))

class ChartGraph(webapp.RequestHandler):
  def get(self):
    path = os.path.join(os.path.dirname(__file__), 'chartgraph.html')
    self.response.out.write(template.render(path, {}))

class UpdateCategory(webapp.RequestHandler):
  def post(self):
    key = self.request.get("key")
    category = db.get(db.Key(key))
    user = users.get_current_user()
    if category.user != user:
      self.response.set_status(403)
      return
    category.name = self.request.get("name")
    category.put()
    self.redirect("/category")

class ArrangeCategory(webapp.RequestHandler):
  def post(self):
    user = users.get_current_user()
    r = re.compile('&*category_list%5B%5D=')
    categories = r.split(self.request.body)
    categories.remove('')
    i=0
    for category in categories:
      ca = db.get(db.Key(category))
      if ca.user != user:
        self.response.set_status(403)
        return
      ca.position = i
      ca.put()
      i += 1
    self.response.out.write('');

class EditAccount(webapp.RequestHandler):
  def get(self):
    user = users.get_current_user()
    key = self.request.get("key")
    account = db.get(db.Key(key))
    if account.user != user:
      self.response.set_status(403)
      return
    path = os.path.join(os.path.dirname(__file__), 'editaccount.html')
    self.response.out.write(template.render(path, {'account':account}))

class EditDayReserve(webapp.RequestHandler):
  def get(self):
    user = users.get_current_user()
    key = self.request.get("key")
    reserve = db.get(db.Key(key))
    if reserve.user != user:
      self.response.set_status(403)
      return
    path = os.path.join(os.path.dirname(__file__), 'edit_day_reserve.html')
    self.response.out.write(template.render(path, {'reserve':reserve}))

class UpdateAccount(webapp.RequestHandler):
  def post(self):
    user = users.get_current_user()
    key = self.request.get("key")
    account = db.get(db.Key(key))
    if account.user != user:
      self.response.set_status(403)
      return
    common.setMemCacheData(user,account.category,account.date.year,account.date.month,-1*account.price);
    account.content = self.request.get("content")
    account.price = int(self.request.get("price"))
    year= int(self.request.get("account_year"))
    month= int(self.request.get("account_month"))
    day = int(self.request.get("account_day"))
    account.date = datetime.datetime(year,month,day)
    account.category = db.Key(self.request.get("category"))
    account.put()
    common.setMemCacheData(user,account.category,year,month,account.price);
    self.redirect("/?year="+str(account.date.year)+"&month="+str(account.date.month)+"&day="+str(account.date.day))

class UpdateDayReserve(webapp.RequestHandler):
  def post(self):
    user = users.get_current_user()
    key = self.request.get("key")
    reserve = db.get(db.Key(key))
    if reserve.user != user:
      self.response.set_status(403)
      return
    reserve.content = self.request.get("content")
    reserve.price = int(self.request.get("price"))
    reserve.day = int(self.request.get("day"))
    reserve.category = db.Key(self.request.get("category"))
    reserve.put()
    self.redirect("/reservation")

class DeleteReserve(webapp.RequestHandler):
  def post(self):
    user = users.get_current_user()
    key = self.request.get("key")
    reserve = db.get(db.Key(key))
    if reserve.user != user:
      self.response.set_status(403)
      return
    reserve.delete()
    self.redirect("/reservation")

class DeleteMemcache(webapp.RequestHandler):
  def get(self):
    memcache.flush_all()
    self.redirect("/");

class DispCalendar(webapp.RequestHandler):
  def get(self):
    path = os.path.join(os.path.dirname(__file__), 'calendar.html')
    self.response.out.write(template.render(path, {}))

class Reservation(webapp.RequestHandler):
  def get(self):
    path = os.path.join(os.path.dirname(__file__), 'reservation.html')
    self.response.out.write(template.render(path, {}))

class ExportPage(webapp.RequestHandler):
  def get(self):
    path = os.path.join(os.path.dirname(__file__), 'export.html')
    self.response.out.write(template.render(path, {}))

class ImportPage(webapp.RequestHandler):
  def get(self):
    path = os.path.join(os.path.dirname(__file__), 'import.html')
    self.response.out.write(template.render(path, {}))

class ExportData(webapp.RequestHandler):
  def post(self):
    user = users.get_current_user()
    from_year= int(self.request.get("start_date_span_year"))
    from_month= int(self.request.get("start_date_span_month"))
    from_day = int(self.request.get("start_date_span_day"))
    from_date = datetime.datetime(from_year,from_month,from_day)

    to_year= int(self.request.get("end_date_span_year"))
    to_month= int(self.request.get("end_date_span_month"))
    to_day = int(self.request.get("end_date_span_day"))
    to_date = datetime.datetime(to_year,to_month,to_day)

    if self.request.get("data_type") == "account":
      query = Spending.all().filter('user',user).filter('date >=',from_date).filter('date <=',to_date).order('date')
      if query.count() > 160:
        path = os.path.join(os.path.dirname(__file__), 'export.html')
        self.response.out.write(template.render(path, {'err_msg':
                               '該当件数が'+str(query.count())+'件ありました。ダウンロードできる件数は160件です。'}))
        return
      # 文字コードはShift_JISとする     
      self.response.headers['Content-Type'] = "application/x-csv; charset=Shift_JIS"
      title = u'"日付","項目","金額","内容"'
      self.response.out.write(title.encode('Shift_JIS') + "\r\n")
      for q in query:
        date = str(q.date.year) + "/" + str(q.date.month) + "/" + str(q.date.day)
        category = string.replace(q.category.name, '"', '""')
        ca = category.encode('Shift_JIS')
        price = q.price
        content= string.replace(q.content, '"', '""')
        con = content.encode("Shift_JIS")
        self.response.out.write('"%s","%s","%d","%s"\r\n' % (date, ca, price,con))
    else :
      query = Daymemo.all().filter('user',user).filter('date >=',from_date).filter('date <=',to_date).order('date')
      if query.count() > 160:
        path = os.path.join(os.path.dirname(__file__), 'export.html')
        self.response.out.write(template.render(path, {'err_msg':
                               '該当件数が'+str(query.count())+'件ありました。ダウンロードできる件数は160件です。'}))
        return
      # 文字コードはShift_JISとする     
      self.response.headers['Content-Type'] = "application/x-csv; charset=Shift_JIS"
      title = u'"日付","メモ"'
      self.response.out.write(title.encode('Shift_JIS') + "\r\n")
      for q in query:
        date = str(q.date.year) + "/" + str(q.date.month) + "/" + str(q.date.day)
        memo1 = string.replace(q.memo, '"', '""')
        memo = memo1.encode("Shift_JIS")
        self.response.out.write('"%s","%s"\r\n' % (date, memo))

class ImportData(webapp.RequestHandler):
  def post(self):
    user = users.get_current_user()
    rawfile = self.request.get('file')
    csvfile = csv.reader(StringIO(rawfile))
    if self.request.get("data_type") == "account":
      for row in csvfile:
        date_arr = row[0].split("/")
        if len(date_arr) != 3:
          continue
        date = datetime.datetime(int(date_arr[0]),int(date_arr[1]),int(date_arr[2]))
        item = db.GqlQuery("SELECT * FROM Category WHERE name = :1 ",unicode(row[1],"Shift_JIS"))
        category = None
        if item.count() == 0:
          category = Category(name=unicode(row[1],"Shift_JIS"),user=user,position=0)
          category.put()
        else:
          category = item[0]
        price = int(row[2])
        content = unicode(row[3],"Shift_JIS")

        spending = Spending(user=user,
                          content=content,
                          price = price,
                          category = category,
                          date = date)
        spending.put()
        common.setMemCacheData(user,spending.category,date.year,date.month,spending.price)
    else:
      for row in csvfile:
        date_arr = row[0].split("/")
        if len(date_arr) != 3:
          continue
        date = datetime.datetime(int(date_arr[0]),int(date_arr[1]),int(date_arr[2]))
        memo = unicode(row[1],"Shift_JIS")
        data = Daymemo.all().filter('user',user).filter('date =',date)
        memoData = None
        if data.count() == 0:
          memoData  = Daymemo(memo=memo,user=user,date=date)
        else:
          memoData = data[0]
          memoData.memo = memoData.memo + "\n" + memo
        memoData.put()
    self.redirect("/")
def main():
  logging.getLogger().setLevel(logging.DEBUG)
  application = webapp.WSGIApplication(
                                       [('/', MainPage),
                                       ('/listaccount', ListAccount),
                                       ('/listmemo', ListMemo),
                                       ('/reservation', Reservation),
                                       ('/category', CategoryList),
                                       ('/addAccount', AddAccount),
                                       ('/addDayReserve', AddDayReserve),
                                       ('/addCategory', AddCategory),
                                       ('/account.json',GetAccountData),
                                       ('/linegraph',LineGraph),
                                       ('/chartgraph',ChartGraph),
                                       ('/lineGraph.json',LineGraphData),
                                       ('/chartGraph.json',ChartGraphData),
                                       ('/accountList.json',GetAccountList),
                                       ('/day_reserves.json',GetReserveList),
                                       ('/deleteCategory',DeleteCategoryData),
                                       ('/memoList.json',GetMemoListData),
                                       ('/memo.json',GetMemoData),
                                       ('/setMemo',SetMemoData),
                                       ('/deleteAccount',DeleteAccountData),
                                       ('/gettotalaccount',GetTotalAccountData),
                                       ('/categories.json',GetCategories),
                                       ('/renewCategory',UpdateCategory),
                                       ('/editAccount',EditAccount),
                                       ('/updateAccount',UpdateAccount),
                                       ('/arrangecategory',ArrangeCategory),
                                       ('/editDayReserve',EditDayReserve),
                                       ('/deleteReserve',DeleteReserve),
                                       ('/updateDayReserve',UpdateDayReserve),
                                       ('/deleteMemcache',DeleteMemcache),
                                       ('/calendar',DispCalendar),
                                       ('/export',ExportPage),
                                       ('/import',ImportPage),
                                       ('/export.csv',ExportData),
                                       ('/importData',ImportData),
                                         ],
                                       debug=True)
  wsgiref.handlers.CGIHandler().run(application)
if __name__ == "__main__":
  main()
